﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System.Diagnostics;

namespace LS.Screening.Core
{
    /// <summary>
    /// Http请求拦截器
    /// </summary>
    public class GlobalRequestFilterAttribute : ActionFilterAttribute, IExceptionFilter
    {
        private Stopwatch stopwatch;
        private Tuple<bool, HttpRequestEnableAttribute> checkResult = null;
        private RequestLog httpRequestLog = null;
        private readonly ILogger<GlobalRequestFilterAttribute> logger;

        public GlobalRequestFilterAttribute(ILogger<GlobalRequestFilterAttribute> logger)
        {
            this.logger = logger;
        }

        /// <summary>
        /// 1、OnActionExecuting
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            base.OnActionExecuting(context);
            stopwatch = Stopwatch.StartNew();
            stopwatch.Start();
            checkResult = context.CheckIsEnable<HttpRequestEnableAttribute, HttpRequestDisableAttribute>();
            if (checkResult?.Item1 == true)
            {
                httpRequestLog = context.AddLog(checkResult.Item2);
                httpRequestLog.Url = context.HttpContext.Request.Path.Value;
                httpRequestLog.Tags += $",{nameof(OnActionExecuting)}";
            }
        }

        /// <summary>
        /// 2、OnActionExecuted
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            base.OnActionExecuted(context);
            if (httpRequestLog != null)
                httpRequestLog.Tags += $",{nameof(OnActionExecuted)}";
            if (checkResult?.Item1 == true && context.Exception == null)
            {
                stopwatch.Stop();
                httpRequestLog.ElapsedMilliseconds = stopwatch.ElapsedMilliseconds;
                httpRequestLog.IsSuccess = true;
                var result = context.Result;
                if (result != null)
                {
                    switch (result)
                    {
                        case ObjectResult objectResult:
                            httpRequestLog.ReturnValue = objectResult.Value;
                            break;

                        case JsonResult jsonResult:
                            httpRequestLog.ReturnValue = jsonResult.Value;
                            break;

                        case ContentResult contentResult:
                            httpRequestLog.ReturnValue = contentResult.Content;
                            break;
                    }
                }
                //logger.Info("测试", httpRequestLog, httpRequestLog.Tags.Split(","));
            }
        }

        /// <summary>
        /// 3、OnException
        /// </summary>
        /// <param name="context"></param>
        public void OnException(ExceptionContext context)
        {
            if (context.ExceptionHandled == false)
            {
                var exceptionLog = context.AddLog(checkResult?.Item2?.AppName, httpRequestLog?.Parameters);
                exceptionLog.Tags += $",{nameof(OnException)}";
                context.ExceptionHandled = true;
                //logger.Error("异常", exceptionLog, exceptionLog.Tags.Split(","));
            }
        }
    }
}
